home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / lfschkpt / lfschkpt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-09  |  14.6 KB  |  482 lines

  1. /* 
  2.  * lfschkpt.c --
  3.  *
  4.  *    The lfschkpt program - A program to display and edit the the
  5.  *    superblock and checkpoint header info of an LFS file system.
  6.  *
  7.  * Copyright 1989 Regents of the University of California
  8.  * Permission to use, copy, modify, and distribute this
  9.  * software and its documentation for any purpose and without
  10.  * fee is hereby granted, provided that the above copyright
  11.  * notice appear in all copies.  The University of California
  12.  * makes no representations about the suitability of this
  13.  * software for any purpose.  It is provided "as is" without
  14.  * express or implied warranty.
  15.  */
  16.  
  17. #ifndef lint
  18. static char rcsid[] = "$Header: /sprite/src/admin/lfschkpt/RCS/lfschkpt.c,v 1.1 91/05/31 13:01:22 mendel Exp $ SPRITE (Berkeley)";
  19. #endif /* not lint */
  20.  
  21. #include "lfslib.h"
  22.  
  23. #ifdef _HAS_PROTOTYPES
  24. #include <varargs.h>
  25. #endif
  26.  
  27. #include <sprite.h>
  28. #include <stdio.h>
  29. #include <option.h>
  30. #include <sys/types.h>
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include <sys/file.h>
  34. #include <unistd.h>
  35. #include <bstring.h>
  36.  
  37. /*
  38.  * NOCHANGE - No change requested in attributes.
  39.  */
  40.  
  41. #define NOCHANGE    (-2)
  42.  
  43. int    maxNumCacheBlocks = NOCHANGE;
  44. int    checkpointInterval = NOCHANGE;
  45. int    domainNumber = NOCHANGE;
  46. int    serverID = NOCHANGE;
  47. int    minNumClean = NOCHANGE;
  48. int    minFreeBlocks = NOCHANGE;
  49. int    wasteBlocks = NOCHANGE;
  50. int    numSegsToClean = NOCHANGE;
  51.  
  52. Boolean    bothFlag = FALSE;
  53. Boolean    writeFlag = FALSE;
  54.  
  55. int    blockSize = 512;        /* Block size of file system. */
  56.  
  57. char    *deviceName;
  58.  
  59. Option optionArray[] = {
  60.     {OPT_DOC, (char *) NULL,  (char *) NULL,
  61.     "This program displays and allows for changing fields of the superblock\n and checkpoint headers of LFS file systems.\n Synopsis: \"lfschkpt [switches] deviceName\"\n Command-line switches are: (-2 means don't change)"},
  62.     {OPT_INT, "maxNumCacheBlocks", (Address) &maxNumCacheBlocks, 
  63.         "Max number of file cache blocks to used during cleaning."},
  64.     {OPT_INT, "checkpointInterval", (Address) &checkpointInterval, 
  65.         "Frequency of checkpoint in seconds."},
  66.     {OPT_INT, "domainNumber", (Address) &domainNumber, 
  67.         "Domain number of file system."},
  68.     {OPT_INT, "serverID", (Address) &serverID, 
  69.         "Sprite ID of server for this disk."},
  70.     {OPT_INT, "minNumClean", (Address) &minNumClean, 
  71.         "Min number of clean segments to maintain in system."},
  72.     {OPT_INT, "minFreeBlocks", (Address) &minFreeBlocks, 
  73.         "Min number of free blocks to maintain on disk."},
  74.     {OPT_INT, "wasteBlocks", (Address) &wasteBlocks, 
  75.         "Maximum number of blocks to waste in a segment."},
  76.     {OPT_INT, "numSegsToClean", (Address) &numSegsToClean, 
  77.         "Num segments above minNumClean before cleaning stops."},
  78.     {OPT_TRUE, "both", (char *) &bothFlag, 
  79.         "Show both checkpoint regions"},
  80.     {OPT_TRUE, "write", (char *) &writeFlag, 
  81.         "Apply the specified changes to the disk without asking."},
  82. };
  83. /*
  84.  * Forward routine declartions. 
  85.  */
  86.  
  87. extern void panic();
  88. static void PrintSuperBlock _ARGS_((LfsSuperBlock *superBlockPtr));
  89. static void PrintCheckPointHdr _ARGS_((LfsCheckPointHdr *headerPtr, int region));
  90. extern int Read _ARGS_((int diskFd, int blockOffset, int bufferSize, 
  91.             char *bufferPtr));
  92.  
  93. extern int Write _ARGS_((int diskFd, int blockOffset, int bufferSize, 
  94.             char *bufferPtr));
  95.  
  96.  
  97. /*
  98.  *----------------------------------------------------------------------
  99.  *
  100.  * main --
  101.  *
  102.  *    Main routine of lfschkpt - parse arguments and do the work.
  103.  *
  104.  * Results:
  105.  *    None.
  106.  *
  107.  * Side effects:
  108.  *    None.
  109.  *
  110.  *----------------------------------------------------------------------
  111.  */
  112.  
  113. int
  114. main(argc,argv)
  115.     int    argc;
  116.     char *argv[];
  117. {
  118.     int       diskFd, cpHdrBlocks, changed, choose, cpSize;
  119.     LfsCheckPointHdr    *checkPointHdr[2];
  120.     LfsSuperBlock *superBlockPtr;
  121.  
  122.  
  123.     argc = Opt_Parse(argc, argv, optionArray, Opt_Number(optionArray), 0);
  124.     if (argc != 2) { 
  125.          Opt_PrintUsage(argv[0], optionArray, Opt_Number(optionArray));
  126.      exit(1);
  127.     } else {
  128.     deviceName = argv[1];
  129.     }
  130.     diskFd = open(deviceName, writeFlag ? O_RDWR : O_RDONLY, 0);
  131.     if (diskFd < 0) {
  132.     fprintf(stderr,"%s:", argv[0]);
  133.     perror(deviceName);
  134.     exit(-1);
  135.     }
  136.     superBlockPtr = (LfsSuperBlock *) malloc(LFS_SUPER_BLOCK_SIZE);
  137.     if (superBlockPtr == (LfsSuperBlock *)  NULL) {
  138.     fprintf(stderr,"%s:Can't malloc memory for superblock\n", deviceName);
  139.     exit(1);
  140.     }
  141.     if (Read(diskFd, LFS_SUPER_BLOCK_OFFSET, LFS_SUPER_BLOCK_SIZE, 
  142.         (char *)superBlockPtr) != LFS_SUPER_BLOCK_SIZE) {
  143.     fprintf(stderr,"%s:Can't read superblock.\n", deviceName);
  144.     exit(-1);
  145.  
  146.     }
  147.     if (superBlockPtr->hdr.magic != LFS_SUPER_BLOCK_MAGIC) {
  148.     fprintf(stderr,"%s:Bad magic number for filesystem\n", deviceName);
  149.     exit(-1);
  150.     }
  151.     PrintSuperBlock(superBlockPtr);
  152.  
  153.     cpHdrBlocks = (sizeof(LfsCheckPointHdr) + blockSize - 1)/blockSize;
  154.     cpSize = blockSize * cpHdrBlocks;
  155.     checkPointHdr[0] = (LfsCheckPointHdr *) malloc(cpSize);
  156.     checkPointHdr[1] = (LfsCheckPointHdr *) malloc(cpSize);
  157.     if ((checkPointHdr[0] == (LfsCheckPointHdr *) NULL) ||
  158.     (checkPointHdr[1] == (LfsCheckPointHdr *) NULL)) {
  159.     fprintf(stderr,"%s:Can't malloc memory for checkpoints\n", deviceName);
  160.     exit(1);
  161.     }
  162.  
  163.     /*
  164.      * Examine the two checkpoint areas to locate the checkpoint area with the
  165.      * newest timestamp.
  166.      */
  167.     if (Read(diskFd, superBlockPtr->hdr.checkPointOffset[0], cpSize,
  168.          (char *) (checkPointHdr[0])) != cpSize) {
  169.     fprintf(stderr,"%s:Can't read checkPointHeader 0.\n", deviceName);
  170.     free((char *) checkPointHdr[0]);
  171.     checkPointHdr[0] = (LfsCheckPointHdr *) NULL;
  172.     }
  173.     if (Read(diskFd, superBlockPtr->hdr.checkPointOffset[1], cpSize,
  174.          (char *) (checkPointHdr[1])) != cpSize) {
  175.     fprintf(stderr,"%s:Can't read checkPointHeader 1.\n", deviceName);
  176.     free((char *) checkPointHdr[1]);
  177.     checkPointHdr[1] = (LfsCheckPointHdr *) NULL;
  178.     }
  179.     if ((checkPointHdr[0] == (LfsCheckPointHdr *) NULL) &&
  180.     (checkPointHdr[1] == (LfsCheckPointHdr *) NULL)) {
  181.     fprintf(stderr,"%s:Can't read either checkPointHeader.\n", deviceName);
  182.     exit(-1);
  183.     }
  184.     if ((checkPointHdr[0] == (LfsCheckPointHdr *) NULL) ||
  185.     (checkPointHdr[1]->timestamp > checkPointHdr[0]->timestamp)) {
  186.     choose = 1;
  187.     } else {
  188.     choose = 0;
  189.     }
  190.     PrintCheckPointHdr(checkPointHdr[choose], choose);
  191.     if (bothFlag) {
  192.      PrintCheckPointHdr(checkPointHdr[!choose], !choose);
  193.     }
  194.  
  195. #define    CHANGEIT(newval, name, oldval, flag)    \
  196.     if ((newval) != NOCHANGE) { \
  197.         printf("Changing %s from %d to %d\n",(name),(oldval),(newval));\
  198.         (oldval) = (newval); \
  199.         (flag) = TRUE; \
  200.     }
  201.  
  202.     changed = FALSE;
  203.  
  204.     CHANGEIT(maxNumCacheBlocks, "maxNumCacheBlocks", 
  205.         superBlockPtr->hdr.maxNumCacheBlocks, changed);
  206.     CHANGEIT(checkpointInterval, "checkpointInterval", 
  207.         superBlockPtr->hdr.checkpointInterval, changed);
  208.  
  209.  
  210.     CHANGEIT(minNumClean, "minNumClean", 
  211.         superBlockPtr->usageArray.minNumClean, changed);
  212.     CHANGEIT(minFreeBlocks, "minFreeBlocks", 
  213.         superBlockPtr->usageArray.minFreeBlocks, changed);
  214.     CHANGEIT(wasteBlocks, "wasteBlocks", 
  215.         superBlockPtr->usageArray.wasteBlocks, changed);
  216.     CHANGEIT(numSegsToClean, "numSegsToClean", 
  217.         superBlockPtr->usageArray.numSegsToClean, changed);
  218.  
  219.     if (changed) { 
  220.     if(!writeFlag) {
  221.         printf("CHANGES NOT APPLIED TO DISK - Use -write option\n");
  222.         changed = FALSE;
  223.     }
  224.     }
  225.  
  226.     if (changed) {
  227.         if (Write(diskFd, LFS_SUPER_BLOCK_OFFSET, LFS_SUPER_BLOCK_SIZE, 
  228.         (char *)superBlockPtr) != LFS_SUPER_BLOCK_SIZE) {
  229.         fprintf(stderr,"%s:Can't rewrite superblock.\n", deviceName);
  230.         exit(-1);
  231.     }
  232.     }
  233.  
  234.     changed = FALSE;
  235.     CHANGEIT(domainNumber, "domainNumber", 
  236.         checkPointHdr[choose]->domainNumber, changed);
  237.     CHANGEIT(serverID, "serverID", 
  238.         checkPointHdr[choose]->serverID, changed);
  239.  
  240.     if (changed) { 
  241.     if(!writeFlag) {
  242.         printf("CHANGES NOT APPLIED TO DISK - Use -write option\n");
  243.         changed = FALSE;
  244.     }
  245.     }
  246.     if (changed) {
  247.     if (Write(diskFd, superBlockPtr->hdr.checkPointOffset[choose], cpSize,
  248.              (char *) (checkPointHdr[choose])) != cpSize) {
  249.         fprintf(stderr,"%s:Can't write checkPointHeader %d.\n", deviceName,
  250.                     choose);
  251.     }
  252.     exit(-1);
  253.     }
  254.  
  255.     exit(0);
  256.     return 0;
  257. }
  258.  
  259.  
  260. /*
  261.  *----------------------------------------------------------------------
  262.  *
  263.  * PrintSuperBlock --
  264.  *
  265.  *    Print super block contents.
  266.  *
  267.  * Results:
  268.  *    None.
  269.  *
  270.  * Side effects:
  271.  *    None.
  272.  *
  273.  *----------------------------------------------------------------------
  274.  */
  275. static void
  276. PrintSuperBlock(superBlockPtr)
  277.     LfsSuperBlock *superBlockPtr;
  278. {
  279.     printf("SuperBlock.hdr.version: %d\n", superBlockPtr->hdr.version);
  280.     printf("SuperBlock.hdr.blockSize: %d\n", 
  281.                 superBlockPtr->hdr.blockSize);
  282.     printf("SuperBlock.hdr.maxCheckPointBlocks: %d\n", 
  283.                 superBlockPtr->hdr.maxCheckPointBlocks);
  284.     printf("SuperBlock.hdr.checkPointOffset[0]: %d\n", 
  285.             superBlockPtr->hdr.checkPointOffset[0]);
  286.     printf("SuperBlock.hdr.checkPointOffset[1]: %d\n", 
  287.             superBlockPtr->hdr.checkPointOffset[1]);
  288.     printf("SuperBlock.hdr.logStartOffset: %d\n", 
  289.             superBlockPtr->hdr.logStartOffset);
  290.     printf("SuperBlock.hdr.checkpointInterval: %d\n", 
  291.             superBlockPtr->hdr.checkpointInterval);
  292.     printf("SuperBlock.hdr.maxNumCacheBlocks: %d\n", 
  293.             superBlockPtr->hdr.maxNumCacheBlocks);
  294.     printf("SuperBlock.descMap.version: %d\n", superBlockPtr->descMap.version);
  295.     printf("SuperBlock.descMap.maxDesc: %d\n", superBlockPtr->descMap.maxDesc);
  296.     printf("SuperBlock.descMap.stableMem.blockSize: %d\n", 
  297.             superBlockPtr->descMap.stableMem.blockSize);
  298.     printf("SuperBlock.descMap.stableMem.entrySize: %d\n", 
  299.             superBlockPtr->descMap.stableMem.entrySize);
  300.     printf("SuperBlock.descMap.stableMem.maxNumEntries: %d\n", 
  301.             superBlockPtr->descMap.stableMem.maxNumEntries);
  302.     printf("SuperBlock.descMap.stableMem.entriesPerBlock: %d\n", 
  303.             superBlockPtr->descMap.stableMem.entriesPerBlock);
  304.     printf("SuperBlock.descMap.stableMem.maxNumBlocks: %d\n", 
  305.             superBlockPtr->descMap.stableMem.maxNumBlocks);
  306.     printf("SuperBlock.usageArray.segmentSize: %d\n", 
  307.                 superBlockPtr->usageArray.segmentSize);
  308.     printf("SuperBlock.usageArray.numberSegments: %d\n", 
  309.                 superBlockPtr->usageArray.numberSegments);
  310.     printf("SuperBlock.usageArray.minNumClean: %d\n", 
  311.                 superBlockPtr->usageArray.minNumClean);
  312.     printf("SuperBlock.usageArray.minFreeBlocks: %d\n", 
  313.                 superBlockPtr->usageArray.minFreeBlocks);
  314.     printf("SuperBlock.usageArray.wasteBlocks: %d\n", 
  315.                 superBlockPtr->usageArray.wasteBlocks);
  316.     printf("SuperBlock.usageArray.numSegsToClean: %d\n", 
  317.                 superBlockPtr->usageArray.numSegsToClean);
  318.     printf("SuperBlock.usageArray.stableMem.blockSize: %d\n", 
  319.             superBlockPtr->usageArray.stableMem.blockSize);
  320.     printf("SuperBlock.usageArray.stableMem.entrySize: %d\n", 
  321.             superBlockPtr->usageArray.stableMem.entrySize);
  322.     printf("SuperBlock.usageArray.stableMem.maxNumEntries: %d\n", 
  323.             superBlockPtr->usageArray.stableMem.maxNumEntries);
  324.     printf("SuperBlock.usageArray.stableMem.entriesPerBlock: %d\n", 
  325.             superBlockPtr->usageArray.stableMem.entriesPerBlock);
  326.     printf("SuperBlock.usageArray.stableMem.maxNumBlocks: %d\n", 
  327.             superBlockPtr->usageArray.stableMem.maxNumBlocks);
  328.     printf("SuperBlock.fileLayout.descPerBlock: %d\n", 
  329.                 superBlockPtr->fileLayout.descPerBlock);
  330. }
  331.  
  332.  
  333. /*
  334.  *----------------------------------------------------------------------
  335.  *
  336.  * PrintCheckPointHdr --
  337.  *
  338.  *    Print check point header contents.
  339.  *
  340.  * Results:
  341.  *    None.
  342.  *
  343.  * Side effects:
  344.  *    None.
  345.  *
  346.  *----------------------------------------------------------------------
  347.  */
  348. static void
  349. PrintCheckPointHdr(headerPtr, region)
  350.     LfsCheckPointHdr *headerPtr;
  351.     int region;
  352. {
  353.     printf("CheckPointHdr[%d].timestamp: %d\n", region, headerPtr->timestamp);
  354.     printf("CheckPointHdr[%d].size: %d\n", region, headerPtr->size);
  355.     printf("CheckPointHdr[%d].version: %d\n", region, headerPtr->version);
  356.     printf("CheckPointHdr[%d].domainPrefix: %s\n", region, 
  357.                     headerPtr->domainPrefix);
  358.     printf("CheckPointHdr[%d].domainNumber: %d\n", region,
  359.                 headerPtr->domainNumber);
  360.     printf("CheckPointHdr[%d].attachSeconds: %d\n", region, 
  361.             headerPtr->attachSeconds);
  362.     printf("CheckPointHdr[%d].detachSeconds: %d\n", region, 
  363.             headerPtr->detachSeconds);
  364.     printf("CheckPointHdr[%d].serverID: %d\n", region, 
  365.             headerPtr->serverID);
  366. }
  367.  
  368.  
  369. /*
  370.  *----------------------------------------------------------------------
  371.  *
  372.  * Read --
  373.  *
  374.  *    Read data from disk.
  375.  *
  376.  * Results:
  377.  *    The number of bytes returned.  -1 if error.
  378.  *
  379.  * Side effects:
  380.  *    None.
  381.  *
  382.  *----------------------------------------------------------------------
  383.  */
  384. int
  385. Read(diskFd, blockOffset, bufferSize, bufferPtr)
  386.     int    diskFd;        /* File descriptor of disk. */
  387.     int    blockOffset;    /* Block offset to start read. */
  388.     char *bufferPtr;    /* Buffer to place data. */
  389.     int     bufferSize;    /* Size of buffer. */
  390. {
  391.     int    status;
  392.     int    blocks;
  393.     char *bufPtr;
  394.  
  395.  
  396.     /*
  397.      * Seek to the start of the blocks to read.
  398.      */
  399.     status = lseek(diskFd, blockOffset*blockSize, L_SET);
  400.     if (status < 0) {
  401.     fprintf(stderr,"%s:", deviceName);
  402.     perror("lseek");
  403.     return status;
  404.     }
  405.     /*
  406.      * Read the blocks handling the case the a request that is not a 
  407.      * multiple number of blocks by reading to a temp buffer and copying.
  408.      */
  409.     blocks = (bufferSize + blockSize-1)/blockSize;
  410.     if (bufferSize != blocks * blockSize) { 
  411.     bufPtr = malloc(blocks*blockSize);
  412.     } else {
  413.     bufPtr = bufferPtr;
  414.     }
  415.     status = read(diskFd, bufPtr, blocks*blockSize);
  416.     if (status != blocks*blockSize) {
  417.     if (status < 0) {
  418.         fprintf(stderr,"%s:", deviceName);
  419.         perror("read device");
  420.         return status;
  421.     }
  422.     fprintf(stderr,"%s:Short read on device %d != %d\n",deviceName,
  423.         status, blocks*blockSize);
  424.     } else {
  425.     status = bufferSize;
  426.     }
  427.     if (bufPtr != bufferPtr) { 
  428.     bcopy(bufPtr, bufferPtr, bufferSize);
  429.     free(bufPtr);
  430.     }
  431.     return status;
  432. }
  433.  
  434.  
  435. /*
  436.  *----------------------------------------------------------------------
  437.  *
  438.  * Write --
  439.  *
  440.  *    Wrote data to disk.
  441.  *
  442.  * Results:
  443.  *    The number of bytes returned.  -1 if error.
  444.  *
  445.  * Side effects:
  446.  *    None.
  447.  *
  448.  *----------------------------------------------------------------------
  449.  */
  450. int
  451. Write(diskFd, blockOffset, bufferSize, bufferPtr)
  452.     int    diskFd;        /* File descriptor of disk. */
  453.     int    blockOffset;    /* Block offset to start write. */
  454.     char *bufferPtr;    /* Buffer to read data from. */
  455.     int     bufferSize;    /* Size of buffer. */
  456. {
  457.     int    status;
  458.  
  459.  
  460.     /*
  461.      * Seek to the start of the blocks to read.
  462.      */
  463.     status = lseek(diskFd, blockOffset*blockSize, L_SET);
  464.     if (status < 0) {
  465.     fprintf(stderr,"%s:", deviceName);
  466.     perror("lseek");
  467.     return status;
  468.     }
  469.     status = write(diskFd, bufferPtr, bufferSize);
  470.     if (status != bufferSize) {
  471.     if (status < 0) {
  472.         fprintf(stderr,"%s:", deviceName);
  473.         perror("write device");
  474.         return status;
  475.     }
  476.     fprintf(stderr,"%s:Short write on device %d != %d\n",deviceName,
  477.         status, bufferSize);
  478.     } 
  479.     return status;
  480. }
  481.  
  482.